package thread.ex.chrono;

// Version 1 : un nouveau thread est cree lorsqu'on appuie sur START
// Version 2 : on utilise le meme thread, mais le compteur est reinitialise a zero
public class Compteur implements Runnable {

	private int cpt;
	private int cptS;
	private int precision;
	private int chronoH;
	private int chronoM;
	private int chronoS;
	private int chronoDS;
	private int chronoCS;
	private int chronoMS;
	private boolean stop;
	private boolean pause;
	private Thread thread;
	private Object condition = new Object();

	public Compteur() {
		cpt = 0;
		stop = false;
		cptS = 0;
		precision = 1000; // 1000 milli seconds
	}

	public Compteur(int precision) {
		this();
		this.precision = precision;
	}

	public Object getCondition() {
		return condition;
	}

	public int getH() {
		return chronoH;
	}

	public int getM() {
		return chronoM;
	}

	public int getS() {
		return chronoS;
	}

	public int[] getHMS() {
		int chronoMilli = cptS;
		return new int[] { chronoH, chronoM, chronoS, chronoMilli };
	}

	public void initZero() {
		cpt = 0;
		chronoS = 0;
		chronoM = 0;
		chronoH = 0;
	}

	public String currentThreadName() {
		return thread.getName();
	}

	public void launch() {
		pause = false;
		stop = false;
		cpt = 0;
		chronoH = 0;
		chronoM = 0;
		chronoS = 0;
		thread = new Thread(this);
		thread.start();
	}

	public int getCpt() {
		return cpt;
	}
	
	public int getCptS() {
		return cptS;
	}

	public void setStop(boolean stop) {
		this.stop = stop;
	}

	public void pause() {
		pause = true;
	}

	public void resume() {
		synchronized (condition) {
			condition.notify();
		}
	}

	@Override
	public void run() {
		while (!stop) {
			try {
				Thread.sleep(precision);
				synchronized (condition) {
					while (pause) {
						condition.wait();
						pause = false;
					}
				}
				cpt++;
				chrono(cpt, precision);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

	public void chrono(int cpt, int precision) {
		cptS = cpt % (1000 / precision);
		int cs = (cpt * precision / 1000) % (1000 / precision);
		chronoS = cs % 60;
		chronoM = (cs / 60) % 60;
		chronoH = (cs / 3600) % 24;
	}
}
